#ifndef __BLOCK_FILE_H__
#define __BLOCK_FILE_H__

#include <iostream>

#include "stream_file.h"
#include "./includes/register_pack.h"
#include "block.h"
#include "block_factory.h"
#include "block_table.h"
#include "./includes/file_pointer_pack.h"

class BlockFile : public StreamFile::StreamFile{
	private:
		std::fstream free_space_stream;
		BlockFactory blockFactory;
		BlockTable block_table;
		
	public:
		BlockFile(std::string path,openmode mode,const RegisterFactory &regFactory,unsigned int blockSize);
		~BlockFile();
		
		/* Agrega un registro al archivo en el primer bloque con espacio libre, si no
		hay bloque con suficiente espacio, crea uno. Devuelve un BlockPointer*/
		FilePointer* write(const Register& pointer);
		/*Busca el registro en el archivo de bloques y lo devuelve*/
		Register* read(const FilePointer& pointer);
		/*Actualiza el registro, puede que el numero de registro y bloque cambien*/
		FilePointer* update(const Register&, FilePointer&);
		/*Elimina el registro*/
		void free(const FilePointer& pointer);

		void writeBlock(Block& block,unsigned int offset);
		Block* readBlock(unsigned int offset);

		/*TODO-> No implementadas,ni se implementaran dado que no se usan en el TP */				
		FilePointer* first();
		FilePointer* last();
		
		void peek(const FilePointer& pointer,bool back=false);
		Register* readNext(FilePointer& pointer,bool back=false);
		
		std::ostream& toOstream(std::ostream& out);		

	private:
		void freeChainedRegister(const BlockPointer& bp);
		Register* readChainedRegister(Block& block);
		BlockPointer* writeChainedRegister(const Register& reg);
};

#endif /* __BLOCK_FILE_H__ */
